package service

import (
	"context"
	"fmt"
	"math/rand"
	"strconv"
	"time"
	"user-srv/basic/global"
	__ "user-srv/basic/proto"
	"user-srv/internal/model"
	"user-srv/pkg"
)

type Service struct {
	__.UnimplementedUserServer
}

func (s *Service) SendSms(_ context.Context, req *__.SendSmsReq) (resp *__.SendSmsResp, err error) {
	mobile := req.Mobile
	if mobile == "" {
		return nil, fmt.Errorf("手机号不允许为空")
	}

	if len(mobile) < 11 {
		return nil, fmt.Errorf("手机号为11位，请核对手机号位数是否正确")
	}

	code := fmt.Sprintf("%06d", rand.Intn(1000000))

	codeKey := "sendSms" + mobile
	limitKey := "sendSmsNum" + mobile

	count, _ := global.Rdb.Get(global.Ctx, limitKey).Int()
	if count > 3 {
		return nil, fmt.Errorf("5分钟内最多可以发送3次短信")
	}

	result, err := global.Rdb.Exists(global.Ctx, codeKey).Result()
	if err != nil {
		return nil, err
	}

	if result > 0 {
		return nil, fmt.Errorf("当前验证码仍在有效期内")
	}

	err = global.Rdb.Set(global.Ctx, codeKey, code, time.Minute*10).Err()
	if err != nil {
		return nil, err
	}

	pipe := global.Rdb.TxPipeline()
	pipe.Incr(global.Ctx, limitKey)
	if count == 0 {
		pipe.Expire(global.Ctx, limitKey, time.Minute*5)
	}

	_, _ = pipe.Exec(global.Ctx)

	_, err = pkg.SendSms(mobile, code)
	if err != nil {
		return nil, err
	}

	resp = &__.SendSmsResp{Message: "发送成功"}

	return resp, nil

}

func (s *Service) Register(_ context.Context, req *__.RegisterReq) (resp *__.RegisterResp, err error) {

	codeKey := "sendSms" + req.Mobile

	code, err := global.Rdb.Get(global.Ctx, codeKey).Result()

	if err != nil {
		return nil, err
	}

	if code != req.Code {
		return nil, fmt.Errorf("验证码错误")
	}

	user := model.User{
		NickName: "默认昵称" + strconv.Itoa(rand.Intn(1000)),
		Password: req.Password,
		Mobile:   req.Mobile,
		Avatar:   "morentouxiang.jpg",
		Status:   1,
	}

	err = global.DB.Debug().Create(&user).Error
	if err != nil {
		return nil, err
	}

	resp = &__.RegisterResp{Id: int64(user.ID)}

	return resp, nil
}

func (s *Service) Login(_ context.Context, req *__.LoginReq) (resp *__.LoginResp, err error) {

	codeKey := "sendSms" + req.Mobile

	user := model.User{}

	global.DB.Debug().Where("mobile = ?", req.Mobile).First(&user)

	if user.ID == 0 {
		return nil, fmt.Errorf("当前用户尚未注册")
	}

	code, err := global.Rdb.Get(global.Ctx, codeKey).Result()

	if err != nil {
		return nil, err
	}

	if code != req.Code {
		return nil, fmt.Errorf("验证码错误")
	}

	resp = &__.LoginResp{Id: int64(user.ID)}

	return resp, nil
}
